#include <iostream.h>
#include <stdlib.h>
#include <cctype>
#include "../evo/mylib.h"

#define MAX_ROW 100
#define MAX_COL 100
#define MAX_CLS 100
#define N_CLASSES 6

int get_row(char *line, int *row)
{
   int line_ptr, row_ptr;

   /* Si inizilizza il puntatore alla stringa al primo carattere che conti-
      ene un carattere di tipo numerico. */
   line_ptr = 0;
   while(!isdigit(line[line_ptr]))
     ++line_ptr;

  // Si inizializza il primo elemento della riga da caricare.
  row_ptr = 0;


  // Si inizia la scansione della linea.
  do
  {
    // Si carica l'intero puntato dal puntatore a line.
    row[row_ptr++] = atoi(&line[line_ptr]);

    //row_ptr++;

    // Si scandisce la linea fino al prossimo intero.
    while((line[line_ptr] != ',') && (line[line_ptr] != '|') &&
          (line[line_ptr] != '\0'))
      ++line_ptr;

    line_ptr++;
  }
  while ((line[line_ptr] != '|') && (line[line_ptr] != '\0'));


  return (row_ptr);// - 1);
}


float comp_address_index(int data[MAX_ROW][MAX_COL], int cls_num)
{
   float indexes[MAX_CLS], denom, tmp, numer;
   int i, j, weights[MAX_CLS];


   // Inizializzazione
   for (i=0; i <  MAX_CLS; ++i)
      indexes[i] = 0.0;
   for (i=0; i <  MAX_CLS; ++i)
      weights[i] = 0;

   // Si calcolano i pesi dei clusters.
   for (i=0; i < cls_num; ++i)
      for (j=0; j < N_CLASSES; ++j)
         weights[i] += data[j][i];


   // Per ognuna delle classi del problema si calcola il relativo indice.
   for (i=0; i < cls_num; ++i)
   {
      // Si calcola prima il denominatore.
      denom = 0.0;
      for (j=0; j < N_CLASSES; ++j)
         denom += data[j][i];
      denom *=denom;

      // Adesso si calcola l'i-esimo indice.
      tmp = 0.0;
      for (j=0; j < N_CLASSES; ++j)
        tmp += (data[j][i] * data[j][i]) / denom;

      indexes[i] = tmp;
   }

   // ***** Si calcola l'indice globale del custering. ******

   // Si calcola prima il numeratore.
   numer = 0.0;
   for (i=0; i < cls_num; ++i)
      numer += weights[i] * indexes[i];

   // Adesso si calcola il denominatore.
   denom = 0.0;
   for (i=0; i < cls_num; ++i)
      denom += weights[i];


   // Si restituisce il rapporto dei valori appena calcolati.
   return numer / denom;
}

float comp_gathering_index(int data[MAX_ROW][MAX_COL], int cls_num)
{
   float indexes[N_CLASSES], denom, tmp, numer;
   int i, j, weights[N_CLASSES];

   // Inizializzazione
   for (i=0; i <  N_CLASSES; ++i)
      indexes[i] = 0.0;
   for (i=0; i <  N_CLASSES; ++i)
      weights[i] = 0;

   // Si calcolano i pesi dei clusters.
   for (i=0; i < N_CLASSES; ++i)
      for (j=0; j < cls_num; ++j)
         weights[i] += data[i][j];

   // Per ognuna delle classi del problema si calcola il relativo indice.
   for (i=0; i < N_CLASSES; ++i)
   {
      // Si calcola prima il denominatore.
      denom = 0.0;
      for (j=0; j < cls_num; ++j)
         denom += data[i][j];
      denom *=denom;

      // Si calcola l'i-esimo indice.
      tmp = 0.0;
      for (j=0; j < cls_num; ++j)
        tmp += (data[i][j] * data[i][j]) / denom;

      indexes[i] = tmp;
   }

   // ***** Si calcola l'indice globale del custering. ******

   // Si calcola prima il numeratore.
   numer = 0.0;
   for (i=0; i < N_CLASSES; ++i)
      numer += weights[i] * indexes[i];

   // Adesso si calcola il denominatore.
   denom = 0.0;
   for (i=0; i < N_CLASSES; ++i)
      denom += weights[i];


   // Si restituisce il rapporto dei valori appena calcolati.
   return numer / denom;
}


int main(int argc, char *argv[])
{
     char file_name[30], line[100];
     
     ifstream input_stream;
     int data_matrix[MAX_ROW][MAX_COL], row, i, j, cls_num;
     float  gathered_index, addressing_index, final_index;


     if (argc == 1)
       abort_message("Manca il nome del file contente i dati");

     strcpy(file_name, &argv[1][0]);

     input_stream.open(file_name);
     if (!input_stream)
       abort_message("Impossibile aprire il file: %s", file_name);;

     row = 0;

     while (get_line(line, &input_stream, 100))
        cls_num = get_row(line, &data_matrix[row++][0]);

     cout<<endl<<"******* nome file: "<<file_name<<" ************ "<<endl;
     cout<<endl<<"risultati: "<<endl;

     gathered_index   = comp_gathering_index(data_matrix, cls_num);
     addressing_index = comp_address_index(data_matrix, cls_num);

     cout<<endl<<"Numero di classi  ---> "<<cls_num<<endl<<endl;
     cout<<endl<<"G  ---> "<<gathered_index;
     cout<<endl<<"I  ---> "<<addressing_index;
     cout<<endl<<"Ic ---> "<<gathered_index * addressing_index;

     /*
     for (i=0; i < N_CLASSES; ++i)
     {
        cout<<endl;
        for (j=0; j < cls_num; ++j)
           cout<<data_matrix[i][j]<<" ";
     } */


     return 0;
}
